﻿using System;
using System.Collections;
using System.Collections.Generic;
using Fine.Collections.Intf;
using JetBrains.Annotations;



namespace Fine.Collections.Views
{
    /// <summary>
    /// Adapts RIterator of <b>S</b> to RIterator of <b>T</b>.
    /// </summary>
    /// <typeparam name="S">the source item type.</typeparam>
    /// <typeparam name="T">the destination item type.</typeparam>
    public class RIteratorAdaptor<S,T> : RIterator<T>,
                                         IEnumerator<T>
    {
        [NotNull]
        protected readonly RIterator<S> it;

        [NotNull]
        protected readonly Converter<S,T> converter;


        /// <summary>
        /// Constructs an RIterator adaptor.
        /// </summary>
        /// <param name="iterator">source iterator.</param>
        /// <param name="converter">converting function.</param>
        public RIteratorAdaptor([NotNull] RIterator<S> iterator, [NotNull] Converter<S,T> converter)
        {
            if (iterator == null) throw new ArgumentNullException("iterator");
            if (converter == null) throw new ArgumentNullException("converter");
            this.it = iterator;
            this.converter = converter;
        }


        public void Reset()
        {
            it.Reset(); 
        }


        public bool Next()
        {
            return it.Next();
        }


        bool IEnumerator.MoveNext()
        {
            return it.Next();
        }


        public T Current
        {
            get { return converter(it.Current); }
        }


        object IEnumerator.Current
        {
            get { return converter(it.Current); }
        }


        public RIterator<T> Clone()
        {
            var srcIteratorClone = it.Clone();
            return new RIteratorAdaptor<S, T>(srcIteratorClone, converter);
        }


        public void Dispose()
        {
            it.Dispose();
        }
    }
}
